home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util1 / snowblnk.lha / SnowBlank / Source / Snow / blank.c next >
C/C++ Source or Header  |  1995-11-15  |  6KB  |  265 lines

  1. /* --------------------------------------------------------------------
  2.  *
  3.  *             A christmas blanker inspired by xsnow
  4.  *
  5.  *    initialization/cleanup code copied from the dragon module
  6.  *      (dragon module: (C)Alexander Kneer and Michael D. Bayne)
  7.  * 
  8.  * -------------------------------------------------------------------- */
  9.  
  10.  
  11. #include <exec/memory.h>
  12. #include <math.h>
  13. #include <stdlib.h>
  14.  
  15. #include "/includes.h"
  16.  
  17. #define STAGES 2        /* Number of different shapes */
  18. #define BLANKDELAY 100        /* This many snowflakes are displayed before
  19.                  * we check if to continue blanking */
  20. #define COUNTLIMIT 6        /* max. number of moves in one direction */
  21. #define COUNTMIN 1        /* min. number of moves in one direction */
  22.  
  23. /* random generation function macros */
  24. #define COUNTFUNC RangeRand(COUNTLIMIT-COUNTMIN)+COUNTMIN
  25. #define DXFUNC    RangeRand(5)-2;
  26. #define DYFUNC    RangeRand(2)+1;
  27.  
  28. typedef enum { false, true } bool;
  29.  
  30. bool BIGFLAKES;
  31. int  NUMSNOW;
  32. bool COLLECT;
  33.  
  34. int patx[10] = {  -1,-1, 1, 1, 0  , -1, 1, 0, 0, 0 };
  35. int paty[10] = {  -1, 1,-1, 1, 0  ,  0, 0, 1,-1, 0 };
  36.  
  37. int *collect;
  38.  
  39. typedef struct 
  40.   { int x,y;            /* The current coordinates */
  41.     int dx,dy;            /* Movement direction is (dx,dy) */
  42.     int count;            /* How long to keep direction dx */
  43.     int stage;            /* STAGES different shapes */
  44.   } snowflake;
  45.  
  46.  
  47. Triplet *ColorTable = 0L;
  48.  
  49.  
  50. #define PR_FLAKE   0
  51. #define PR_BIG     2
  52. #define PR_COLLECT 4
  53. #define PR_MODE    6
  54.  
  55. VOID Defaults( PrefObject *Prefs )
  56. {
  57.   Prefs[PR_FLAKE].po_Level = 200;
  58.   Prefs[PR_BIG].po_Level = 1;
  59.   Prefs[PR_COLLECT].po_Level = 1;
  60.   Prefs[PR_MODE].po_ModeID = getTopScreenMode();
  61. }
  62.  
  63.  
  64. /* Remove a single snowflake's image from the screen */
  65. __inline void undraw(snowflake *flake, struct RastPort *rp)
  66.   if (BIGFLAKES)
  67.     {
  68.       int *startx = patx + 5*(flake->stage);
  69.       int *starty = paty + 5*(flake->stage);
  70.       int i;
  71.       SetAPen(rp,0);
  72.       for (i=0; i<5; i++)
  73.     { WritePixel(rp,flake->x+(*startx),flake->y+(*starty));
  74.       startx++;
  75.       starty++;
  76.     }
  77.     }
  78.   else
  79.     {
  80.       SetAPen(rp,0);
  81.       WritePixel(rp,flake->x,flake->y);
  82.     }
  83. }
  84.  
  85.  
  86. /* Draw a single snowflake's image to the screen */
  87. __inline void draw(snowflake *flake, struct RastPort *rp)
  88.   if (BIGFLAKES)
  89.     {
  90.       int *startx = patx + 5*(flake->stage);
  91.       int *starty = paty + 5*(flake->stage);
  92.       int i;
  93.       SetAPen(rp,1);
  94.       for (i=0; i<5; i++)
  95.     { WritePixel(rp,flake->x+(*startx),flake->y+(*starty));
  96.       startx++;
  97.       starty++;
  98.     }
  99.     }
  100.   else
  101.     { SetAPen(rp,1);
  102.       WritePixel(rp,flake->x,flake->y);
  103.     }
  104. }
  105.  
  106.  
  107. /* change the position of a snowflake. If it leaves [0..width]x[0..height],
  108.  * generate a new one with coordinates (<random>,0) */
  109. __inline void update(snowflake *curr, int width, int height, struct RastPort *rp)
  110. { bool gen_new;
  111.   int oldx = curr->x;
  112.   if (curr->count > 0)
  113.     { curr->y = curr->y + curr->dy;
  114.       if (curr->y >= height-1)
  115.     { gen_new = true;
  116.     }
  117.       else
  118.     { curr->x = curr->x + curr->dx;
  119.       if (curr->x < 1 || curr->x >= width-1)
  120.         { gen_new = true;
  121.         }
  122.       else 
  123.         { gen_new = false;
  124.           (curr->count)--;
  125.           if (curr->count <= 0)
  126.         { curr->dx = DXFUNC;
  127.           curr->count = COUNTFUNC;
  128.         }
  129.           if (curr->stage)
  130.         { curr->stage--;
  131.         }
  132.           else
  133.         { curr->stage = STAGES-1;
  134.         }
  135.         }
  136.     }
  137.     }
  138.   
  139.   /* do we have to compute a new flake? */
  140.   if (gen_new)
  141.     { if (collect && curr->y > height-3)
  142.     { collect[oldx]--;
  143.       if (collect[oldx]<height-20)
  144.         { collect[oldx]=height-20;
  145.         }
  146.       
  147.       curr->x = oldx;
  148.       curr->y = collect[oldx];
  149.       draw(curr,rp);
  150.     }
  151.       curr->x = RangeRand(width-2)+1;
  152.       curr->y = 1;
  153.       curr->dx = DXFUNC;
  154.       curr->dy = DYFUNC;
  155.       curr->count = COUNTFUNC;
  156.       curr->stage = RangeRand(STAGES);
  157.     }
  158. }
  159.  
  160.  
  161.  
  162.  
  163. LONG snow(struct Screen *scr, SHORT width, SHORT height)
  164. {
  165.   unsigned int i;
  166.   LONG flg_end;
  167.   snowflake *flake,*curr;
  168.   int blankcount;
  169.   struct RastPort *rp = &(scr->RastPort);
  170.  
  171.   /* initialize the snow array */
  172.   flake = malloc(NUMSNOW*sizeof(snowflake));
  173.   curr = flake;
  174.   for (i=0; i<NUMSNOW; i++)
  175.     { curr->x = RangeRand(width-2)+1;
  176.       curr->y = RangeRand(height-2)+1;
  177.       curr->dx = DXFUNC;
  178.       curr->dy = DYFUNC;
  179.       curr->count = COUNTFUNC;
  180.       curr->stage = RangeRand(STAGES);
  181.       curr++;
  182.     }
  183.  
  184.   /* and the collect array */
  185.   if (COLLECT)
  186.     { collect = malloc(sizeof(int)*width);
  187.       for (i=0; i<width; i++)
  188.         { collect[i] = height-2;
  189.         }
  190.       collect[0] = 0;
  191.       collect[width-1] = 0;
  192.     }
  193.   else
  194.     { collect = NULL;
  195.     }
  196.  
  197.   /* Update all snowflakes forever. Update includes removal from the screen,
  198.    * computation of new position, drawing on the screen */
  199.   blankcount = BLANKDELAY;
  200.   while (1)
  201.     { curr = flake;
  202.       for (i=0; i<NUMSNOW; i++)
  203.     { /* Remove curr's image */
  204.       undraw(curr,rp);
  205.       /* compute new position and appearance */
  206.       update(curr,width,height,rp);
  207.       /* and display it */
  208.       draw(curr,rp);
  209.       /* can we continue? */
  210.       if (!blankcount)
  211.         { blankcount = BLANKDELAY;
  212.           flg_end = ContinueBlanking();
  213.           ScreenToFront(scr);
  214.           if (flg_end != OK)
  215.         { free(flake);
  216.           if (collect) free(collect);
  217.           return flg_end;
  218.         }
  219.         }
  220.       else
  221.         { blankcount--;
  222.         }
  223.       curr++;
  224.     }
  225.     }
  226.   return OK;            /* just for the compiler */
  227. }
  228.  
  229.  
  230. LONG Blank( PrefObject *Prefs )
  231. {
  232.     struct Screen *Scr;
  233.     struct Window *Wnd;
  234.     LONG RetVal;
  235.     
  236.         BIGFLAKES = Prefs[PR_BIG].po_Level;
  237.     NUMSNOW   = Prefs[PR_FLAKE].po_Level;
  238.     COLLECT   = Prefs[PR_COLLECT].po_Level;
  239.  
  240.     if( Scr = OpenScreenTags( NULL, SA_Depth, 1,
  241.                              SA_Quiet, TRUE, SA_DisplayID, Prefs[PR_MODE].po_ModeID,
  242.                              SA_Behind, TRUE, SA_Overscan, OSCAN_STANDARD,
  243.                              TAG_DONE ))
  244.     {
  245.         SetRGB4(&( Scr->ViewPort ), 0, 0, 0, 0 );
  246.         ColorTable = RainbowPalette( Scr, 0L, 1L, 0L );
  247.         SetRGB4(&( Scr->ViewPort ), 1, 15, 15, 15 );
  248.         Wnd = BlankMousePointer( Scr );
  249.         
  250.         do
  251.             RetVal = snow( Scr, Scr->Width, Scr->Height );
  252.         while( RetVal == OK );
  253.         
  254.         UnblankMousePointer( Wnd );
  255.         RainbowPalette( 0L, ColorTable, 1L, 0L );
  256.         CloseScreen( Scr );
  257.     }
  258.     else
  259.         RetVal = FAILED;
  260.     
  261.     return RetVal;
  262. }
  263.